﻿using IWshRuntimeLibrary;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using File = System.IO.File;

namespace MainApp.Utils
{
    /// <summary>
    /// 程序自启动帮助类
    /// </summary>
    public class AutoStartHelper
    {
        /// <summary>
        /// 设置开机自动启动-只需要调用改方法就可以了参数里面的bool变量是控制开机启动的开关的，默认为开启自启启动
        /// </summary>
        /// <param name="appName">应用程序名称，作为快捷方式名称，如：testapp</param>
        /// <param name="appStartupPath">应用程序路径</param>
        /// <param name="onOff">自启开关。true为开启自启动，false为关闭自启动</param>
        /// <returns></returns>
        public static bool SetMeAutoStart(string appName, string appStartupPath, bool onOff)
        {
            if (string.IsNullOrWhiteSpace(appName))
                throw new ArgumentException($"参数'{nameof(appName)}'为空");
            if (string.IsNullOrWhiteSpace(appStartupPath))
                throw new ArgumentException($"参数'{nameof(appStartupPath)}'为空");
            try
            {
                //获取启动路径应用程序快捷方式的路径集合
                var userStartPath = GetUserStartPath();
                var commonStartPath = GetCommonStartPath();
                var userShortcutPaths = GetShortcutsFromFolder(userStartPath, appStartupPath);
                var commonShortcutPaths = GetShortcutsFromFolder(commonStartPath, appStartupPath);
                //始终删除掉“公用”启动目录下面的快捷方式
                if ((commonShortcutPaths?.Count ?? 0) > 0)
                {
                    for (int i = 0; i < commonShortcutPaths.Count; i++)
                    {
                        DeleteFile(commonShortcutPaths[i]);
                    }
                }
                //开机启动
                if (onOff)
                {
                    //不存在则创建快捷方式
                    if ((userShortcutPaths?.Count ?? 0) == 0)
                        return CreateShortcut(userStartPath, appName, appStartupPath, appName);
                    //存在2个以快捷方式则保留一个快捷方式-避免重复
                    if ((userShortcutPaths?.Count ?? 0) >= 2)
                    {
                        for (int i = 1; i < userShortcutPaths.Count; i++)
                        {
                            DeleteFile(userShortcutPaths[i]);
                        }
                    }
                    return true;
                }
                //开机不启动
                //存在快捷方式则遍历全部删除
                if ((userShortcutPaths?.Count ?? 0) > 0)
                {
                    for (int i = 0; i < userShortcutPaths.Count; i++)
                    {
                        DeleteFile(userShortcutPaths[i]);
                    }
                }
                return true;
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 在桌面上创建快捷方式-如果需要可以调用
        /// </summary>
        /// <param name="appName">应用程序名称，作为快捷方式名称，如：testapp</param>
        /// <param name="appStartupPath">应用程序路径</param>
        /// <param name="description">描述信息，如果为空则使用应用程序名称</param>
        /// <returns></returns>
        public static bool CreateDesktopQuick(string appName, string appStartupPath, string description = "")
        {
            if (string.IsNullOrWhiteSpace(appName))
                throw new ArgumentException($"参数'{nameof(appName)}'为空");
            if (string.IsNullOrWhiteSpace(appStartupPath))
                throw new ArgumentException($"参数'{nameof(appStartupPath)}'为空");
            try
            {
                var desktopPath = GetdesktopPath();
                var shortcutPaths = GetShortcutsFromFolder(desktopPath, appStartupPath);
                //如果没有则创建
                if ((shortcutPaths?.Count ?? 0) > 0)
                    return true;
                if (string.IsNullOrWhiteSpace(description))
                    description = appName;
                return CreateShortcut(desktopPath, appName, appStartupPath, description);
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 设置为开机启动(修改注册表-需要以管理员方式运行)
        /// </summary>
        /// <param name="appName">应用程序名称，作为快捷方式名称，如：testapp</param>
        /// <param name="appStartupPath">应用程序路径</param>
        /// <param name="onOff">自启开关。true为开启自启动，false为关闭自启动</param>
        /// <returns></returns>
        public static bool SetMeAutoStartByRegistry(string appName, string appStartupPath, bool onOff)
        {
            try
            {
                //打开注册表子项
                RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                if (key == null)//如果该项不存在的话，则创建该子项
                    key = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
                if (onOff)
                {
                    //设置为开机启动
                    key.SetValue(appName, appStartupPath);
                    key.Close();
                    return true;
                }
                //取消开机启动
                key.DeleteValue(appName);
                key.Close();
                return true;
            }
            catch { }
            return false;
        }

        /// <summary>
        /// 获取用户自动启动目录
        /// </summary>
        /// <remarks><see cref="Environment.SpecialFolder.Startup"/></remarks>
        private static string GetUserStartPath() => Environment.GetFolderPath(Environment.SpecialFolder.Startup);

        /// <summary>
        /// 获取公用自动启动目录
        /// </summary>
        /// <remarks><see cref="Environment.SpecialFolder.CommonStartup"/></remarks>
        private static string GetCommonStartPath() => Environment.GetFolderPath(Environment.SpecialFolder.CommonStartup);

        /// <summary>
        /// 获取桌面目录
        /// </summary>
        private static string GetdesktopPath() => Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

        /// <summary>
        ///  向目标路径创建指定文件的快捷方式
        /// </summary>
        /// <param name="directory">目标目录</param>
        /// <param name="shortcutName">快捷方式名字</param>
        /// <param name="targetPath">文件完全路径</param>
        /// <param name="description">描述</param>
        /// <param name="iconLocation">图标地址</param>
        /// <returns>成功或失败</returns>
        private static bool CreateShortcut(string directory, string shortcutName, string targetPath, string description = null, string iconLocation = null)
        {
            try
            {
                //检查快捷方式目录
                if (!Directory.Exists(directory))
                    Directory.CreateDirectory(directory);
                //添加引用 Com 中搜索 Windows Script Host Object Model
                var shortcutPath = Path.Combine(directory, string.Format("{0}.lnk", shortcutName));
                var shell = new WshShell();
                //创建快捷方式对象
                var shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);
                //指定目标路径
                shortcut.TargetPath = targetPath;
                //设置起始位置
                shortcut.WorkingDirectory = Path.GetDirectoryName(targetPath);
                //设置运行方式，默认为常规窗口
                shortcut.WindowStyle = 1;
                //设置备注
                shortcut.Description = description;
                //设置图标路径
                shortcut.IconLocation = string.IsNullOrWhiteSpace(iconLocation) ? targetPath : iconLocation;
                //保存快捷方式
                shortcut.Save();
                return true;
            }
            catch (Exception ex) { }
            return false;
        }

        /// <summary>
        /// 获取指定文件夹下指定应用程序的快捷方式路径集合
        /// </summary>
        /// <param name="directory">文件夹</param>
        /// <param name="targetPath">目标应用程序路径</param>
        /// <returns>目标应用程序的快捷方式</returns>
        private static List<string> GetShortcutsFromFolder(string directory, string targetPath)
        {
            var shortcuts = new List<string>();
            var files = Directory.GetFiles(directory, "*.lnk");
            if ((files?.Length ?? 0) == 0)
                return shortcuts;
            for (int i = 0; i < files.Length; i++)
            {
                var shortcutAppPath = GetAppPathFromShortcut(files[i]);
                if (shortcutAppPath.Equals(targetPath, StringComparison.CurrentCultureIgnoreCase))
                    shortcuts.Add(files[i]);
            }
            return shortcuts;
        }

        /// <summary>
        /// 获取快捷方式的目标文件路径-用于判断是否已经开启了自动启动
        /// </summary>
        /// <param name="shortcutPath"></param>
        /// <returns></returns>
        private static string GetAppPathFromShortcut(string shortcutPath)
        {
            //快捷方式文件的路径 = @"d:\Test.lnk";
            if (!File.Exists(shortcutPath))
                return string.Empty;
            var shell = new WshShell();
            var shortct = (IWshShortcut)shell.CreateShortcut(shortcutPath);
            //快捷方式文件指向的路径.Text = 当前快捷方式文件IWshShortcut类.TargetPath;
            //快捷方式文件指向的目标目录.Text = 当前快捷方式文件IWshShortcut类.WorkingDirectory;
            return shortct.TargetPath;
        }

        /// <summary>
        /// 根据路径删除文件-用于取消自启时从计算机自启目录删除程序的快捷方式
        /// </summary>
        /// <param name="path">路径</param>
        private static void DeleteFile(string path)
        {
            var attr = File.GetAttributes(path);
            if (attr == FileAttributes.Directory)
                Directory.Delete(path, true);
            else
                File.Delete(path);
        }
    }
}
